#region  == Copyright == 
// =====================================================================
//  Microsoft Consulting Services France - Aymeric Mouillé - 2013
//  Projet     : CRM Solution Management Tool
//  Fichier    : JobHistoryControl.cs (30/04/2013 16:49)
//  
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// =====================================================================
#endregion

namespace CRM.Solution.Management.Tool.Controls
{
    #region  == Using == 
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Windows.Forms;

    using Microsoft.Xrm.Sdk.Query;

    #endregion

    /// <summary>
    /// </summary>
    public partial class JobHistoryControl : UserControl
    {
        /// <summary>
        /// The bg worker jobs
        /// </summary>
        private readonly BackgroundWorker BgWorkerJobs;

        /// <summary>
        /// The job items
        /// </summary>
        private List<JobItem> JobItems;

        #region Main Form
        /// <summary>
        /// Gets the main form.
        /// </summary>
        /// <value>
        /// The main form.
        /// </value>
        private MainForm MainForm
        {
            get
            {
                return (MainForm)Parent.Parent.Parent;
            }
        }
        #endregion

        #region = Constructor =
        /// <summary>
        /// Initializes a new instance of the <see cref="JobHistoryControl" /> class.
        /// </summary>
        public JobHistoryControl()
        {
            InitializeComponent();
            BgWorkerJobs = new BackgroundWorker();
        }
        #endregion

        #region Load Control
        /// <summary>
        /// Loads the control.
        /// </summary>
        public void LoadControl()
        {
            BgWorkerJobs.DoWork += BgWorkerJobsOnDoWork;
            BgWorkerJobs.RunWorkerCompleted += BgWorkerJobsOnRunWorkerCompleted;
            if (!BgWorkerJobs.IsBusy)
            {
                MainForm.UpdateStripStatus("Loading, please wait ...");
                BgWorkerJobs.RunWorkerAsync();
            }
        }
        #endregion

        #region Bg Worker Jobs On Do Work
        /// <summary>
        /// Bgs the worker jobs on do work.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="doWorkEventArgs">
        /// The <see cref="DoWorkEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerJobsOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            GetAllJobs();
        }
        #endregion

        #region Bg Worker Jobs On Run Worker Completed
        /// <summary>
        /// Bgs the worker jobs on run worker completed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="runWorkerCompletedEventArgs">
        /// The <see cref="RunWorkerCompletedEventArgs" /> instance containing the event data.
        /// </param>
        private void BgWorkerJobsOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
        {
            if (JobItems == null)
            {
                return;
            }
            if (JobItems.Count > 0)
            {
                dgvJobs.DataSource = JobItems.OrderBy(j => j.CompletedOn).ToList();
            }
            MainForm.UpdateStripStatus(string.Format("{0} job(s) loaded!", JobItems.Count), 100);
            MainForm.CanTryAgain(JobItems.Count == 0);
        }
        #endregion

        #region Get All Jobs
        /// <summary>
        /// Gets all jobs.
        /// </summary>
        private void GetAllJobs()
        {
            JobItems = new List<JobItem>();

            MainForm.UpdateStripStatus("Querying for import jobs ...");
            var query = new QueryExpression("importjob") { ColumnSet = new ColumnSet(true) };

            try
            {
                var response = MainForm.OrganizationService.RetrieveMultiple(query);
                MainForm.UpdateStripStatus("Processing results ...");
                foreach (var importJob in response.Entities)
                {
                    var jobItem = new JobItem();
                    jobItem.JobId = importJob.Id;
                    jobItem.Name = importJob["name"].ToString();
                    if (importJob.Attributes.Contains("solutionname"))
                    {
                        jobItem.SolutionName = importJob["solutionname"].ToString();
                    }
                    if (importJob.Attributes.Contains("startedon"))
                    {
                        jobItem.CreatedOn = importJob["startedon"].ToString();
                    }
                    if (importJob.Attributes.Contains("completedon"))
                    {
                        jobItem.CompletedOn = importJob["completedon"].ToString();
                    }
                    if (importJob.Attributes.Contains("progress"))
                    {
                        jobItem.Progress = Convert.ToDecimal(importJob["progress"]);
                    }
                    if (importJob.Attributes.Contains("data"))
                    {
                        jobItem.LogData = importJob["data"].ToString();
                        jobItem.Status = SolutionHelper.GetImportLogStatus(jobItem.LogData);
                    }

                    JobItems.Add(jobItem);
                }
            }
            catch (Exception ex)
            {
                MainForm.UpdateStripStatus(string.Format("Failed to retrieve results! ({0})", ex.Message));
                if (MessageBox.Show(ex.Message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry)
                {
                    GetAllJobs();
                }
            }
        }
        #endregion

        #region Btn Get Log Click
        /// <summary>
        /// Handles the Click event of the btnGetLog control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">
        /// The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void btnGetLog_Click(object sender, EventArgs e)
        {
            if (dgvJobs.SelectedRows.Count == 1)
            {
                var jobItem = (JobItem)dgvJobs.SelectedRows[0].DataBoundItem;
                string filePath = string.Format("{0}.xml", jobItem.SolutionName);
                File.WriteAllText(filePath, jobItem.LogData);

                // TODO : do this better!
                Process.Start("excel.exe", filePath);
            }
        }
        #endregion

        #region Btn Refresh Click
        /// <summary>
        /// Handles the Click event of the btnRefresh control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">
        /// The <see cref="EventArgs" /> instance containing the event data.
        /// </param>
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            BgWorkerJobs.DoWork += BgWorkerJobsOnDoWork;
            BgWorkerJobs.RunWorkerCompleted += BgWorkerJobsOnRunWorkerCompleted;
            if (!BgWorkerJobs.IsBusy)
            {
                MainForm.UpdateStripStatus("Loading, please wait ...");
                BgWorkerJobs.RunWorkerAsync();
            }
        }
        #endregion
    }
}
